package com.cgc.venus.server.core.harbor.client;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.squareup.okhttp.*;
import com.cgc.venus.server.core.bean.response.VenusResponseStatus;
import com.cgc.venus.server.core.exception.VenusException;
import com.cgc.venus.server.core.harbor.model.*;
import com.cgc.venus.server.core.utils.StringUtil;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.net.ssl.*;
import java.io.IOException;
import java.net.CookieManager;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
@ConfigurationProperties(prefix = "harbor")
public class HarborClient {
    private static final String REQUEST_RESPONSE_INFO = "Request: [%s], Response: [%s]";
    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    private OkHttpClient okhttpClient;
    private ObjectMapper mapper = new ObjectMapper();
    private String baseUrl;
    private String adminUser;
    private String adminPassword;
    private static Map<Integer, String> harborApiResponseStatus = new HashMap<Integer, String>();

    static {
        harborApiResponseStatus.put(200, "ok");
        harborApiResponseStatus.put(201, "Project created successfully.");
        harborApiResponseStatus.put(400, "Unsatisfied with constraints of the project creation.");
        harborApiResponseStatus.put(401, "User need to log in first.");
        harborApiResponseStatus.put(403, "User does not have permission to the project.");
        harborApiResponseStatus.put(404, "Project ID does not exist.");
        harborApiResponseStatus.put(409, "Project name already exists.");
        harborApiResponseStatus.put(412, "Project contains policies, can not be deleted.");
        harborApiResponseStatus.put(500, "Unexpected internal errors.");
    }

    public String getAdminUser() {
        return adminUser;
    }

    public void setAdminUser(String adminUser) {
        this.adminUser = adminUser;
    }

    public String getAdminPassword() {
        return adminPassword;
    }

    public void setAdminPassword(String adminPassword) {
        this.adminPassword = adminPassword;
    }

    private boolean verifySSL = false;

    public void setBaseUrl(String baseUrl) {
        this.baseUrl = baseUrl;
    }


    private CookieManager cookieManager;

    public CookieManager getCookieManager() {
        return cookieManager;
    }

    /**
     *
     */
    public HarborClient() {
        getOkHttpClient();
    }

    /**
     * @param baseUrl
     */
    public HarborClient(String baseUrl) {
        this(baseUrl, false);
    }

    /**
     * @param baseUrl
     * @param verifySSL
     */
    public HarborClient(String baseUrl, boolean verifySSL) {
        this.baseUrl = baseUrl;
        this.verifySSL = verifySSL;
        getOkHttpClient();
    }

    /**
     * append '/' to baseUrl if it doesn't end with '/'
     *
     * @return
     */
    public String getBaseUrl() {
        if (!this.baseUrl.endsWith("/")) {
            this.baseUrl += "/";
        }
        return this.baseUrl;
    }

    /**
     * 获取OkHttpClient
     *
     * @return
     */
    private void getOkHttpClient() {
        try {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                @Override
                public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType)
                        throws CertificateException {
                }

                @Override
                public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType)
                        throws CertificateException {
                }

                @Override
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return new java.security.cert.X509Certificate[0];
                }
            }};
            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            okhttpClient = new OkHttpClient();
            okhttpClient.setSslSocketFactory(sslSocketFactory);
            //okhttpClient.setHostnameVerifier((String hostname, SSLSession session) -> !HarborClient.this.verifySSL);
            okhttpClient.setHostnameVerifier(new HostnameVerifier() {
                public boolean verify(String hostname, SSLSession sslSession) {
                    return !HarborClient.this.verifySSL;
                }
            });
            cookieManager = new CookieManager();
            okhttpClient.setCookieHandler(cookieManager);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 登录
     *
     * @param name
     * @param password
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public int login(String name, String password) throws IOException, VenusException {
        String url = getBaseUrl().replace("/api", "") + "login?principal=" + name + "&password=" + password;
        RequestBody reqbody = RequestBody.create(null, new byte[0]);
        Request request = new Request.Builder().post(reqbody).url(url).build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return code;
    }

    /**
     * 登出
     *
     * @return
     * @throws IOException
     */
    public int logout() throws IOException {
        String url = getBaseUrl().replace("/api", "") + "log_out";
        Request request = new Request.Builder().get().url(url).build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        return code;
    }

    /**
     * 实现get /search   Search for projects and repositories
     *
     * @param q
     * @return
     * @throws IOException
     */
    public Search search(String q) throws IOException, VenusException {
        String url = getBaseUrl() + "search?q=" + q;
        Request request = new Request.Builder().url(url).get().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return mapper.readValue(response.body().string(), Search.class);
    }

    /**
     * 实现get /projects   List projects
     *
     * @param name      The name of project.
     * @param isPublic  The project is public or private.
     * @param owner     The name of project owner.
     * @param page      The page nubmer, default is 1.
     * @param page_size The size of per page, default is 10, maximum is 100.
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public List<Project> getProjects(String name, boolean isPublic, String owner, int page, int page_size) throws IOException, VenusException {
        List<NameValuePair> qparams = new ArrayList<NameValuePair>();
        if (!StringUtil.isEmpty(name)) {
            qparams.add(new BasicNameValuePair("name", name));
        }
        qparams.add(new BasicNameValuePair("public", Boolean.toString(isPublic)));
        if (!StringUtil.isEmpty(owner)) {
            qparams.add(new BasicNameValuePair("owner", owner));
        }
        qparams.add(new BasicNameValuePair("page", Integer.toString(page)));
        qparams.add(new BasicNameValuePair("page_size", Integer.toString(page_size)));
        String url = getBaseUrl() + "projects?" + URLEncodedUtils.format(qparams, "UTF-8");
        Request request = new Request.Builder().url(url).get().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return mapper.readValue(response.body().string(), new TypeReference<List<Project>>() {
        });
    }

    /**
     * 实现 HEAD /projects   Check if the project name user provided already exists.
     *
     * @param projectName
     * @return
     * @throws IOException
     */
    public boolean checkProject(String projectName) throws IOException {
        String url = baseUrl + "projects?project_name=" + projectName;
        Request request = new Request.Builder().url(url).head().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            return false;// Project name not exists.";
        }
        return true;//Project name exists.";
    }

    /**
     * 实现post /projects   create a new projects
     *
     * @param name     The name of project.
     * @param isPublic The project is public or private.
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public boolean createProject(String name, boolean isPublic) throws IOException, VenusException {
        String url = baseUrl + "projects";
        Project project = new Project();
        project.setName(name);
        if (isPublic) {
            project.setPublic(1);
        } else {
            project.setPublic(0);
        }
        RequestBody requestBody = RequestBody.create(JSON, mapper.writeValueAsString(project));
        Request request = new Request.Builder().url(url).post(requestBody).build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 201) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return true;//create 成功
    }

    /**
     * 实现delete /projects/{project_id}   delete a project by projectId
     *
     * @param projectName The name of project.
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public boolean deleteProject(String projectName) throws IOException, VenusException {
        Search search = search(projectName);
        List<Object> projects = search.getProject();
        Map project = null;
        if (projects != null && projects.size() > 0) {
            project = (Map) projects.get(0);
        } else {
            return false;
        }
        Integer projectId = (Integer) project.get("project_id");
        String url = baseUrl + "projects/" + projectId;
        Request request = new Request.Builder().url(url).delete().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return true;// 成功
    }


    /**
     * PUT /projects/{project_id}/publicity Update properties for a selected project
     *
     * @param projectId
     * @param project
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public boolean updateProject(int projectId, Project project) throws IOException, VenusException {
        String url = baseUrl + "projects/" + projectId + "/publicity";
        RequestBody requestBody = RequestBody.create(JSON, mapper.writeValueAsString(project));
        Request request = new Request.Builder().url(url).put(requestBody).build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return true;//delete 成功
    }


    /**
     * 实现GET /projects/{project_id}       Return specific project detail infomation
     *
     * @param project_Id project_ids
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public Project getProjectDetal(int project_Id) throws IOException, VenusException {
        String url = getBaseUrl() + "projects/" + project_Id;
        Request request = new Request.Builder().url(url).get().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return mapper.readValue(response.body().string(), new TypeReference<Project>() {
        });
    }

    /**
     * 实现GET /projects/{project_id}       Return specific project detail infomation
     *
     * @param projectName projectName
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public Project getProjectDetal(String projectName) throws IOException, VenusException {
        Search search = search(projectName);
        List<Object> projects = search.getProject();
        Map project = null;
        if (projects != null && projects.size() > 0) {
            project = (Map) projects.get(0);
        } else {
            return null;
        }
        Integer project_Id = (Integer) project.get("project_id");
        String url = getBaseUrl() + "projects/" + project_Id;
        Request request = new Request.Builder().url(url).get().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return mapper.readValue(response.body().string(), new TypeReference<Project>() {
        });
    }


    /**
     * 实现 GET /projects/{project_id}/members/    Return a project's relevant role members.
     *
     * @param projectId
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public List<ProjectMember> getProjectMembers(int projectId) throws IOException, VenusException {
        String url = getBaseUrl() + "projects/" + projectId + "/members/";
        Request request = new Request.Builder().url(url).get().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return mapper.readValue(response.body().string(), new TypeReference<List<ProjectMember>>() {
        });
    }

    /**
     * 实现 POST /projects/{project_id}/members/ Add project role member accompany with relevant project and user
     *
     * @param projectId
     * @param roles
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public boolean addMember(int projectId, MemberConf roles) throws IOException, VenusException {
        String url = baseUrl + "projects/" + projectId + "/members";
        RequestBody requestBody = RequestBody.create(JSON, mapper.writeValueAsString(roles));
        Request request = new Request.Builder().url(url).post(requestBody).build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return true;// 成功
    }

    /**
     * 实现 DELETE /projects/{project_id}/members/{user_id}   Delete project role members accompany with relevant project and user.
     *
     * @param projectId
     * @param userId
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public boolean deleteMember(int projectId, int userId) throws IOException, VenusException {
        String url = baseUrl + "projects/" + projectId + "/members/" + userId;
        Request request = new Request.Builder().url(url).delete().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return true;// 成功
    }

    /**
     * 实现 GET /projects/{project_id}/members/{user_id} Return role members accompany with relevant project and user.
     *
     * @param projectId
     * @param userId
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public Member getMemberDetail(int projectId, int userId) throws IOException, VenusException {
        String url = getBaseUrl() + "projects/" + projectId + "/members/" + userId;
        Request request = new Request.Builder().url(url).get().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return mapper.readValue(response.body().string(), Member.class);
    }


    /**
     * PUT /projects/{project_id}/members/{user_id} Update project role members accompany with relevant project and user.
     *
     * @param projectId
     * @param userId
     * @param roles
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public boolean updateMember(int projectId, int userId, MemberConf roles) throws IOException, VenusException {
        String url = baseUrl + "projects/" + projectId + "/members/" + userId;
        RequestBody requestBody = RequestBody.create(JSON, mapper.writeValueAsString(roles));
        Request request = new Request.Builder().url(url).put(requestBody).build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return true;// 成功
    }

    /**
     * 实现 GET /statistics Get projects number and repositories number relevant to the user
     *
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public ProjectAndRepoNum statisticsProjectAndRepoNum() throws IOException, VenusException {
        String url = getBaseUrl() + "statistics";
        Request request = new Request.Builder().url(url).get().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return mapper.readValue(response.body().string(), ProjectAndRepoNum.class);
    }


    /**
     * 镜像资源查询
     * 实现 GET /repositories Get repositories accompany with relevant project and repo name
     * @param projectId  项目id
     * @param repositoryNameQueryKey  镜像名称查询关键字
     * @param  page The page nubmer, default is 1.
     * @param  page_size The size of per page, default is 10, maximum is 100.
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public List<Repository> getRepositories(int projectId, String repositoryNameQueryKey,int page,int page_size) throws IOException, VenusException {
        String url = getBaseUrl() + "repositories?project_id=" + projectId;
        if (repositoryNameQueryKey != null) {
            url = url + "&q=" + repositoryNameQueryKey;
        }else{
            url = url +"&page="+page+"&page_size="+page_size;
        }
        Request request = new Request.Builder().url(url).get().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return mapper.readValue(response.body().string(), new TypeReference<List<Repository>>() {
        });
    }

    /**
     * 镜像资源查询
     * 实现 GET /repositories Get repositories accompany with relevant project and repo name
     * @param projectName  项目名称
     * @param repositoryNameQueryKey  镜像名称查询关键字
     * @param  page The page nubmer, default is 1.
     * @param  page_size The size of per page, default is 10, maximum is 100.
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public List<Repository> getRepositories(String projectName,String repositoryNameQueryKey,int page,int page_size) throws IOException, VenusException {
        Project project=this.getProjectDetal(projectName);
        if(project==null){
            return null;
        }
        int projectId=project.getProjectId();
        String url = getBaseUrl() + "repositories?project_id=" + projectId;
        if (repositoryNameQueryKey != null) {
            url = url + "&q=" + repositoryNameQueryKey;
        }else{
            url = url +"&page="+page+"&page_size="+page_size;
        }
        Request request = new Request.Builder().url(url).get().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return mapper.readValue(response.body().string(), new TypeReference<List<Repository>>() {
        });
    }

    /**
     * 根据镜像名称查询镜像版本信息
     * 实现 GET /repositories/{repo_name}/tags Get tags of a relevant repository.
     * @param repoName
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public List<Tag> getRepositorieTags(String repoName) throws IOException, VenusException {
        String url = getBaseUrl() + "repositories/"+repoName+"/tags";
        Request request = new Request.Builder().url(url).get().build();
        Response response=null;
        try {
            response = okhttpClient.newCall(request).execute();
        }catch (IOException e){
            throw new VenusException(VenusResponseStatus.IO_EXCEPTION, "io 异常,okhttpClient.newCall执行异常!");
        }
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }

        List<Tag> tmp=null;
        try {
//            System.out.println("=========getRepositorieTags response.body start===========");
//            System.out.println(response.body().string());
//            System.out.println("=========getRepositorieTags response.body end===========");
            tmp=mapper.readValue(response.body().string(), new TypeReference<List<Tag>>() {});
        }catch (IOException e){
            throw new VenusException(VenusResponseStatus.IO_EXCEPTION, "io 异常,response解析异常!");
        }
        return tmp;
    }

    /**
     * 根据镜像名称查询镜像版本信息(单个明细)
     * 实现 GET /repositories/{repo_name}/tags/{tag} Get the tag of the repository.
     * @param repoName
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public Tag getRepositorieTagDetail(String repoName,String tag) throws IOException, VenusException {
        String url = getBaseUrl() + "repositories/"+repoName+"/tags/"+tag;
        Request request = new Request.Builder().url(url).get().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return mapper.readValue(response.body().string(), new TypeReference<Tag>() {
        });
    }


    /**
     * 实现 DELETE /repositories/{repo_name} Delete a repository.
     * @param repoName
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public boolean deleteRepositories(String repoName) throws IOException, VenusException {
        String url = baseUrl + "repositories/"+repoName;
        Request request = new Request.Builder().url(url).delete().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return true;//delete 成功
    }

    /**
     * 实现 DELETE /repositories/{repo_name}/tags/{tag} Delete a tag in a repository.
     * @param repoName
     * @param tag
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public boolean deleteRepositories(String repoName, String tag) throws IOException, VenusException {
        String url = baseUrl + "repositories/"+repoName+"/tags/"+tag;
        Request request = new Request.Builder().url(url).delete().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return true;//delete 成功
    }


    /**
     * 实现 GET /repositories/{repo_name}/tags/{tag}/manifest Get manifests of a relevant repository
     * @param repoName
     * @param tag
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public Manifest getManifest(String repoName, String tag) throws IOException, VenusException {
        String url = getBaseUrl() + "repositories/"+repoName+"/tags/"+tag+"/manifest";
        Request request = new Request.Builder().url(url).get().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return mapper.readValue(response.body().string(), Manifest.class);
    }

    /**
     * 实现前N个镜像下载排名(最收欢迎镜像)
     * 实现 GET /repositories/top Get public repositories which are accessed most.
     * @param count
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public List<Repository> getTopRepositories(int count) throws IOException, VenusException {
        String url = getBaseUrl() + "repositories/top";
        if (count != -1) {
            url = url + "?count=" + count;
        }
        Request request = new Request.Builder().url(url).get().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return mapper.readValue(response.body().string(), new TypeReference<List<Repository>>() {
        });
    }


    /**
     * 实现  GET /logs Get recent logs of the projects which the user is a member of
     * @param lines
     * @param startTime
     * @param endTime
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public List<Log> getLogs(String lines, String startTime, String endTime) throws IOException, VenusException {
        List<NameValuePair> qparams = new ArrayList<NameValuePair>();
        if (!StringUtil.isEmpty(lines)) {
            qparams.add(new BasicNameValuePair("lines", lines));
        }
        if (!StringUtil.isEmpty(startTime)) {
            qparams.add(new BasicNameValuePair("start_time", startTime));
        }
        if (!StringUtil.isEmpty(endTime)) {
            qparams.add(new BasicNameValuePair("end_time", endTime));
        }
        qparams.add(new BasicNameValuePair("lines", lines));
        qparams.add(new BasicNameValuePair("start_time", startTime));
        qparams.add(new BasicNameValuePair("end_time", endTime));
        String url = getBaseUrl() + "/logs?" + URLEncodedUtils.format(qparams, "UTF-8");
        Request request = new Request.Builder().url(url).get().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return mapper.readValue(response.body().string(), new TypeReference<List<Log>>() {
        });
    }


    /**
     * 项目日志过滤
     * GET /projects/{project_id}/logs Get access logs accompany with a relevant project.
     * @param projectId
     * @param accessLog
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public List<Log> filterProjectLog(int projectId, Log accessLog) throws IOException, VenusException {
        List<Log> res = new ArrayList<Log>();
        String url = baseUrl + "projects/" + projectId + "/logs";
        RequestBody requestBody = RequestBody.create(JSON, mapper.writeValueAsString(accessLog));
        Request request = new Request.Builder().url(url).post(requestBody).build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        res = mapper.readValue(response.body().string(), new TypeReference<List<Log>>() {
        });
        return res;
    }


    /**
     * 创建用户
     * POST /users Creates a new user account
     * @param user
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public boolean createUser(ProjectMember user) throws IOException, VenusException {
        HarborResponse result = new HarborResponse();
        String res;
        String url = baseUrl + "users";
        RequestBody requestBody = RequestBody.create(JSON, mapper.writeValueAsString(user));
        Request request = new Request.Builder().url(url).post(requestBody).build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 201) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return true;// 成功
    }


    /**
     * 删除用户
     * DELETE /users/{user_id} Mark a registered user as be removed.
     * @param userId
     * @return
     * @throws IOException
     * @throws VenusException
     */
    public boolean deleteUser(int userId) throws IOException, VenusException {
        String url = baseUrl + "users/" + userId;
        Request request = new Request.Builder().url(url).delete().build();
        Response response = okhttpClient.newCall(request).execute();
        int code = response.code();
        if (code != 200) {
            String msg = harborApiResponseStatus.get(code);
            if (StringUtil.isEmpty(msg)) {
                throw new VenusException(VenusResponseStatus.HARBOR_EXCEPTION, "调用harbor api异常!");
            } else {
                throw new VenusException(code, msg);
            }
        }
        return true;// 成功
    }

    public static void main(String[] args) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            String str="[                                                                                                                       \n" +
                    "  {                                                                                                                     \n" +
                    "    \"digest\": \"sha256:1203304e9fe8369156d08ebf6406dce1d31ec973bd8c18380958ac8a26ff8c67\",                                \n" +
                    "    \"name\": \"8.0\",                                                                                                      \n" +
                    "    \"size\": 168431849,                                                                                                  \n" +
                    "    \"architecture\": \"amd64\",                                                                                            \n" +
                    "    \"os\": \"linux\",                                                                                                      \n" +
                    "    \"docker_version\": \"17.06.2-ce\",                                                                                     \n" +
                    "    \"author\": \"\",                                                                                                       \n" +
                    "    \"created\": \"2018-09-12T20:42:22.931362721Z\",                                                                        \n" +
                    "    \"config\": {                                                                                                         \n" +
                    "      \"labels\": null                                                                                                    \n" +
                    "    },                                                                                                                  \n" +
                    "    \"signature\": null,                                                                                                  \n" +
                    "    \"labels\": []                                                                                                        \n" +
                    "  }                                                                                                                     \n" +
                    "]";
            List<Tag> tmp=mapper.readValue(str, new TypeReference<List<Tag>>() {});
            int i=0;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
